home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / ARPCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-18  |  10.2 KB  |  446 lines

  1. /* ARP commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  *
  6.  * Mods by SM6RPZ
  7.  * 1992-05-28 - Added interface to "arp add ..."-command.
  8.  * 1992-07-26 - Small cosmetic changes here and there.
  9.  */
  10. #include "global.h"
  11. #include "ctype.h"
  12. #include "commands.h"
  13. #include "mbuf.h"
  14. #include "timer.h"
  15. #include "internet.h"
  16. #include "ip.h"
  17. #include "arp.h"
  18. #include "rspf.h"
  19. #include "domain.h"
  20. #include "session.h"
  21.  
  22. #if !defined(_lint)
  23. static char rcsid[] OPTIONAL = "$Id: arpcmd.c,v 1.17 1997/08/19 01:19:22 root Exp root $";
  24. #endif
  25.  
  26. static int Arp_Sort = 1;        /* set Initial sort mode */
  27. int Maxarpq = 5;
  28. char ArpDupcall[AXALEN];
  29. int ArpExpire = ARPLIFE;
  30.  
  31.  
  32. static int doarpsort (int argc, char *argv[], void *p);
  33. static void make_arp_string (struct arp_tab * ap, char *buf);
  34. static int doarpadd (int argc, char *argv[], void *p);
  35. static int doarpdrop (int argc, char *argv[], void *p);
  36. static int doarpflush (int argc, char *argv[], void *p);
  37. static int doarppoll (int argc, char *argv[], void *p);
  38. static int doarpeaves (int argc, char *argv[], void *p);
  39. static int doarpexpire (int argc, char *argv[], void *p);
  40. static int doarpqueue (int argc, char *argv[], void *p);
  41. static int doarpdupcall (int argc, char *argv[], void *p);
  42. static void dumparp (void);
  43.  
  44.  
  45. #ifdef CATALOG
  46. #include "catalog.h"
  47.  
  48. #define CAT arpcmd_catalog
  49.  
  50. #define addusage    __STR(0)
  51. #define noiface        __STR(1)
  52. #define exptime        __STR(2)
  53. #define dropusage    __STR(3)
  54. #define dumpstr        __STR(4)
  55. #define dumpheader    __STR(5)
  56.  
  57. #else /* CATALOG */
  58. static const char addusage[] = "Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n";
  59. static const char noiface[] = "No such interface %s\n";
  60. static const char exptime[] = "Expire time for arp entries (in sec.)";
  61. static const char dropusage[] = "Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n";
  62. static const char dumpstr[] = "received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n";
  63. static const char dumpheader[] = "IP addr         Type           Time Q Address           Interface\n";
  64.  
  65. #endif /* CATALOG */
  66.  
  67.  
  68. static const char publishstr[] = "publish";
  69. static const char addstr[] = "add";
  70. static const char netromstr[] = "netrom";
  71. static const char strCR[] = "%s\n";
  72. static const char maxqueue[] = "Max queue";
  73. static const char unknownstr[] = "[unknown]         ";
  74. static const char publishedstr[] = "(published)";
  75.  
  76.  
  77. static struct cmds Arpcmds[] =
  78. {
  79.     { "add",    doarpadd,    0, 4, "arp add <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>"},
  80.     { "drop",    doarpdrop,    0, 3, "arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>"},
  81.     { "dupcall",    doarpdupcall,    0, 0, NULLCHAR},
  82.     { "eaves",    doarpeaves,    0, 0, NULLCHAR},
  83.     { "expire",    doarpexpire,    0, 0, NULLCHAR},
  84.     { "flush",    doarpflush,    0, 0, NULLCHAR},
  85.     { "maxq",    doarpqueue,    0, 0, NULLCHAR},
  86.     { "poll",    doarppoll,    0, 0, NULLCHAR},
  87.     { "publish",    doarpadd,    0, 4, "arp publish <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>"},
  88.     { "sort",    doarpsort,    0, 0, NULLCHAR},
  89.     { NULLCHAR,    NULL,        0, 0, NULLCHAR}
  90. };
  91.  
  92.  
  93. const char *Arptypes[] =
  94. {
  95.     "NET/ROM",
  96.     "10 Mb Ethernet",
  97.     "3 Mb Ethernet",
  98.     "AX.25",
  99.     "Pronet",
  100.     "Chaos",
  101.     "",
  102.     "Arcnet",
  103.     "Appletalk"
  104. };
  105.  
  106.  
  107.  
  108.  
  109. int
  110. doarp (argc, argv, p)
  111. int argc;
  112. char *argv[];
  113. void *p;
  114. {
  115.     if (argc < 2) {
  116.         dumparp ();
  117.         return 0;
  118.     }
  119.     return subcmd (Arpcmds, argc, argv, p);
  120. }
  121.  
  122.  
  123. static int
  124. doarpadd (argc, argvv, p)
  125. int argc;
  126. char *argvv[];
  127. void *p OPTIONAL;
  128. {
  129. char const **argv = (char const **) argvv;
  130. int16 hardware;
  131. uint32 addr;
  132. char *hwaddr;
  133. struct arp_tab *ap;
  134. struct arp_type *at;
  135. int pub = 0;
  136. struct iface *iface;
  137.  
  138.     if (argv[0][0] == 'p')    /* Is this entry published? */
  139.         pub = 1;
  140.     if ((addr = resolve (argv[1])) == 0) {
  141.         tprintf (Badhost, argv[1]);
  142.         return 1;
  143.     }
  144.     if (argc == 4 && tolower (argv[2][0]) != 'n') {
  145.         tprintf (addusage, pub ? publishstr : addstr);
  146.         return -1;
  147.     }
  148.     /* This is a kludge. It really ought to be table driven */
  149.     switch (tolower (argv[2][0])) {
  150.         case 'n':    /* Net/Rom pseudo-type */
  151.             argc = 5;
  152.             argv[4] = netromstr;    /* Force use of netrom interface */
  153.             hardware = ARP_NETROM;
  154.             break;
  155.         case 'e':    /* "ether" */
  156.             hardware = ARP_ETHER;
  157.             break;
  158.         case 'a':    /* "ax25" */
  159.             switch (tolower (argv[2][1])) {
  160.                 case 'x':
  161.                     hardware = ARP_AX25;
  162.                     break;
  163.                 case 'r':
  164.                     hardware = ARP_ARCNET;
  165.                     break;
  166.                 default:
  167.                     tprintf (addusage, pub ? publishstr : addstr);
  168.                     return -1;
  169.             }
  170.             break;
  171.         case 'm':    /* "mac appletalk" */
  172.             hardware = ARP_APPLETALK;
  173.             break;
  174.         default:
  175.             tprintf (addusage, pub ? publishstr : addstr);
  176.             return -1;
  177.     }
  178.     if ((iface = if_lookup (argv[4])) == NULLIF) {
  179.         tprintf (noiface, argv[4]);
  180.         return 1;
  181.     }
  182.     /* If an entry already exists, clear it */
  183.     if ((ap = arp_lookup (hardware, addr, iface)) != NULLARP)
  184.         arp_drop (ap);
  185.  
  186.     at = &Arp_type[hardware];
  187.     if (at->scan == NULLFP ((char *, const char *))) {
  188.         tputs ("Attach device first\n");
  189.         return 1;
  190.     }
  191.     /* Allocate buffer for hardware address and fill with remaining args */
  192.     hwaddr = mallocw ((unsigned) at->hwalen);
  193.     /* Destination address */
  194.     (void) (*at->scan) (hwaddr, argv[3]);
  195.     ap = arp_add (addr, hardware, hwaddr, pub, iface);    /* Put in table */
  196.     free (hwaddr);        /* Clean up */
  197.     stop_timer (&ap->timer);/* Make entry permanent */
  198.     set_timer (&ap->timer, 0L);
  199. #ifdef  RSPF
  200.     rspfarpupcall (addr, hardware, NULLIF);    /* Do a RSPF upcall */
  201. #endif /* RSPF */
  202.     return 0;
  203. }
  204.  
  205.  
  206. static int
  207. doarpeaves (argc, argv, p)
  208. int argc;
  209. char *argv[];
  210. void *p;
  211. {
  212.     return dosetflag (argc, argv, p, ARP_EAVESDROP, 0);
  213. }
  214.  
  215.  
  216. static int
  217. doarppoll (argc, argv, p)
  218. int argc;
  219. char *argv[];
  220. void *p;
  221. {
  222.     return dosetflag (argc, argv, p, ARP_KEEPALIVE, 0);
  223. }
  224.  
  225.  
  226. static int
  227. doarpdupcall (argc, argv, p)
  228. int argc;
  229. char *argv[];
  230. void *p OPTIONAL;
  231. {
  232.     char tmp[AXBUF];
  233.  
  234.     if (argc < 2) {
  235.         tprintf (strCR, pax25 (tmp, ArpDupcall));
  236.         return 0;
  237.     }
  238.     if (argv[1][0]) {
  239.         if (setcall (ArpDupcall, argv[1]) == -1)
  240.             return -1;
  241.     } else
  242.         *ArpDupcall = 0;
  243.     return 0;
  244. }
  245.  
  246.  
  247. static int
  248. doarpqueue (argc, argv, p)
  249. int argc;
  250. char *argv[];
  251. void *p OPTIONAL;
  252. {
  253.     return setint (&Maxarpq, maxqueue, argc, argv);
  254. }
  255.  
  256.  
  257. static int
  258. doarpexpire (argc, argv, p)
  259. int argc;
  260. char *argv[];
  261. void *p OPTIONAL;
  262. {
  263.     return setint (&ArpExpire, exptime, argc, argv);
  264. }
  265.  
  266.  
  267. /* Remove an ARP entry */
  268. static int
  269. doarpdrop (argc, argvv, p)
  270. int argc;
  271. char *argvv[];
  272. void *p OPTIONAL;
  273. {
  274. char const **argv = (char const **) argvv;
  275. int16 hardware;
  276. uint32 addr;
  277. struct arp_tab *ap;
  278. struct iface *iface;
  279.  
  280.     if ((addr = resolve (argv[1])) == 0) {
  281.         tprintf (Badhost, argv[1]);
  282.         return 1;
  283.     }
  284.     if (argc == 3 && tolower (argv[2][0]) != 'n') {
  285.         tputs (dropusage);
  286.         return -1;
  287.     }
  288.     /* This is a kludge. It really ought to be table driven */
  289.     switch (tolower (argv[2][0])) {
  290.         case 'n':
  291.             argc = 4;
  292.             argv[3] = netromstr;    /* Force use of netrom interface */
  293.             hardware = ARP_NETROM;
  294.             break;
  295.         case 'e':    /* "ether" */
  296.             hardware = ARP_ETHER;
  297.             break;
  298.         case 'a':    /* "ax25" */
  299.             switch (tolower (argv[2][1])) {
  300.                 case 'x':
  301.                     hardware = ARP_AX25;
  302.                     break;
  303.                 case 'r':
  304.                     hardware = ARP_ARCNET;
  305.                     break;
  306.                 default:
  307.                     tputs (dropusage);
  308.                     return -1;
  309.             }
  310.             break;
  311.         case 'm':    /* "mac appletalk" */
  312.             hardware = ARP_APPLETALK;
  313.             break;
  314.         default:
  315.             tputs (dropusage);
  316.             return -1;
  317.     }
  318.     if ((iface = if_lookup (argv[3])) == NULLIF) {
  319.         tprintf (noiface, argv[3]);
  320.         return 1;
  321.     }
  322.     if ((ap = arp_lookup (hardware, addr, iface)) == NULLARP)
  323.         return -1;
  324.     arp_drop (ap);
  325.     return 0;
  326. }
  327.  
  328.  
  329. /* Flush all automatic entries in the arp cache */
  330. static int
  331. doarpflush (argc, argv, p)
  332. int argc OPTIONAL;
  333. char *argv[] OPTIONAL;
  334. void *p OPTIONAL;
  335. {
  336. register struct arp_tab *ap;
  337. struct arp_tab *aptmp;
  338. int i;
  339.  
  340.     for (i = 0; i < HASHMOD; i++) {
  341.         for (ap = Arp_tab[i]; ap != NULLARP; ap = aptmp) {
  342.             aptmp = ap->next;
  343.             if (dur_timer (&ap->timer) != 0)
  344.                 arp_drop (ap);
  345.         }
  346.     }
  347.     return 0;
  348. }
  349.  
  350.  
  351. /* Dump ARP table */
  352. static void
  353. dumparp ()
  354. {
  355. register int i, j, k, flow_tmp;
  356. register struct arp_tab *ap;
  357. char *temp;
  358.  
  359.     flow_tmp = Current->flowmode;
  360.     Current->flowmode = 1;
  361.  
  362.     tprintf (dumpstr, Arp_stat.recv, Arp_stat.badtype, Arp_stat.badaddr, Arp_stat.inreq,
  363.          Arp_stat.replies, Arp_stat.outreq);
  364.  
  365.     for (i = 0, j = 0; i < HASHMOD; i++)
  366.         for (ap = Arp_tab[i]; ap != (struct arp_tab *) NULL; ap = ap->next, j++) ;
  367.  
  368.     if (j) {
  369.  
  370.         tputs (dumpheader);
  371.  
  372.         temp = mallocw ((unsigned) j * 80);
  373.  
  374.         for (i = 0, k = 0; i < HASHMOD; i++) {
  375.             for (ap = Arp_tab[i]; ap != (struct arp_tab *) NULL; ap = ap->next, k += 80)
  376.                 make_arp_string (ap, &temp[k]);
  377.         }
  378.  
  379.         if (Arp_Sort)
  380.             qsort (temp, (size_t) j, 80, (int (*)(const void *, const void *)) strcmp);
  381.  
  382.         for (i = 0, k = 4; i < j; i++, k += 80) {
  383.             tputs (&temp[k]);
  384.             if (tputc ('\n') == EOF)
  385.                 break;
  386.         }
  387.         free (temp);
  388.     }
  389.     Current->flowmode = flow_tmp;
  390. }
  391.  
  392.  
  393. void
  394. make_arp_string (ap, buf)
  395. register struct arp_tab *ap;
  396. char *buf;
  397. {
  398. char e[128];
  399. int a = 0;
  400. char *name;
  401.  
  402.     if (DTranslate && (name = resolve_a (ap->ip_addr, !DVerbose)) != NULLCHAR) {
  403.         strcpy (buf, name);
  404.         a += 4;
  405.         free (name);
  406.     } else
  407.         a = SPRINTF ((buf, "%4.4s", inet_ntobos (ap->ip_addr)));
  408.  
  409.     a += SPRINTF ((&buf[a], "%-15.15s ", inet_ntoa (ap->ip_addr)));
  410.     a += SPRINTF ((&buf[a], "%-14.14s ", smsg (Arptypes, NHWTYPES, (unsigned) ap->hardware)));
  411.     a += SPRINTF ((&buf[a], "%4ld ", read_timer (&ap->timer) / 1000L));
  412.  
  413.     if (ap->state == ARP_PENDING)
  414.         a += SPRINTF ((&buf[a], "%1.1u ", len_q (ap->pending)));
  415.     else
  416.         a += SPRINTF ((&buf[a], "  "));
  417.  
  418.     if (ap->state == ARP_VALID) {
  419.         if (Arp_type[ap->hardware].format != NULL)
  420.             (void) (*Arp_type[ap->hardware].format) (e, ap->hw_addr);
  421.         else
  422.             e[0] = '\0';
  423.         a += SPRINTF ((&buf[a], "%-17.17s ", e));
  424.     } else
  425.         a += SPRINTF ((&buf[a], unknownstr));
  426.  
  427.     if (ap->iface)
  428.         a += SPRINTF ((&buf[a], "%-6.6s ", ap->iface->name));
  429.  
  430.     if (ap->pub)
  431.         a += SPRINTF ((&buf[a], publishedstr));
  432.  
  433.     return;
  434. }
  435.  
  436.  
  437. /* Sort ARP dump */
  438. static int
  439. doarpsort (argc, argv, p)
  440. int argc;
  441. char *argv[];
  442. void *p OPTIONAL;
  443. {
  444.     return setbool (&Arp_Sort, "ARP Sort flag", argc, argv);
  445. }
  446.